class Task < ActiveRecord::Base
  belongs_to :project
  belongs_to :user # responsible of the task
  belongs_to :creator, :class_name=>"User", :foreign_key=>'created_by' # creator of the task
  belongs_to :task # so we can have tasks dependant of others
  has_many :notes, :dependent => :destroy
  has_many :tasks, :dependent => :destroy

  before_destroy { |task|
    # verify that this task is not used as a bookmark
    # could we use dependent ?
    Bookmark.destroy_all("task_id = #{task.id}")
    }

  acts_as_taggable
  acts_as_tree :foreign_key=>'task_id' # TODO: use :counter_cache=>true

  #validates_presence_of :project_id, :title, :on=>:update

  def subremains_or_zero
    self.subremains || 0.0
  end

  def has_subtasks
    subtasks_count > 0
  end
  
  def subtasks_count
    subtasks.size
  end
  
  def subtasks
    tasks.select{|t| t.done == 0}
  end

#  def subtasks_by_state(state)
#    tasks.select{|t| t.done == 0 and t.state==state}
#  end

  def undo
    self.done_on  = nil
    self.done = 0
    task.undo! if task # recursive
  end
  
  def undo!
    undo
    save
  end

  # Caution: this method do not save the task, but children are saved.....
  def mark_done(progress=2)
    progress = progress.to_i
    self.progress = progress
    done_bak = self.done
    self.done   = (progress >= 2 ) ? 1 : 0
    if(self.done == 1)
      self.done_on = Time.now if done_bak == 0 # so we do not change the done date if the task was already done
      self.mark_children_done(progress) # propagate to children
    else
      self.undo # not done, propagated to ascendants
    end
    return self.done!=done_bak
  end
  
  def mark_children_done(progress=2)
    tasks.each { |t|
      t.mark_done(progress)
      t.save
      }
  end
   
  def set_remains(orig_est, cur_est, elapsed)
    self.orig_est    = orig_est if(orig_est!='')
    if cur_est != ''
      self.cur_est     = cur_est
      self.orig_est    = cur_est if self.orig_est == nil
    elsif orig_est != ''
      self.cur_est = orig_est
    else
      self.cur_est = nil
    end
    self.elapsed     = elapsed if elapsed != ''
    if self.cur_est and self.elapsed
      diff     = self.cur_est - self.elapsed
      if diff >=0
        self.remains = diff
      else
        self.cur_est =  self.elapsed
        self.remains = 0
      end
    else
      self.remains = self.cur_est
    end
    self.remains = 0 if self.remains == nil
  end
  
  # compute subremains field and propagate to parents
  def compute_remains 
    self.subremains = tasks.inject(0.0) { |sum,t| (t.done==1 ? sum : (sum + t.subremains.to_f))} + self.remains.to_f
    save
    task.compute_remains if task
  end
  
  # change all subtasks' project
  def propagate_project_change(pid)
    tasks.each { |t|
      t.project_id = pid
      t.save
      t.propagate_project_change(pid)
      }
  end

  # change all subtasks' state
  def propagate_state_change(old, new)
    return if new == 'folder'
    
    tasks.each { |t|
      if t.state != 'folder' and t.state != 'ref'
        t.state = new if (t.state == old or old == 'folder') # change state of subtask only if it share the same old state, or simply if the old was a folder
        t.save
      end
      t.propagate_state_change(old,new)
      }
  end

  
  def priority_print
    return "" if self.priority == nil
    return "P#{self.priority}"
  end

  def begun_print
    return "" if self.progress != 1
    return "(begun)"
  end

  def ancestors_print(sep)
    self.ancestors.collect{|a| a.title}.reverse.join(sep)
  end  
  
end

